//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Windows.Forms;


namespace GuidanceExplorer.Model
{
    public enum ClientFlavour { AuthoringToolkit, Offline, Online, AddIn }

    /// <summary>
    /// Represents the root element of the model.
    /// </summary>
    [MenuItemAttribute(0, "&File", null, Keys.None)]
    [MenuItemAttribute(10, "&Edit", null, Keys.None)]
    [MenuItemAttribute(20, "&View", null, Keys.None)]
    [MenuItemAttribute(30, "&Help", null, Keys.None)]
    [LinkMenuItemAttribute(40, "Submit Feedback", GuidanceExplorer.Commands.SubmitFeedback, Keys.None)]
    public class Guidance : IGuidanceItemContainer
    {
        /// <summary>
        /// Factory.
        /// </summary>
        /// <returns>A new instance of Guidance.</returns>
        public static Guidance New()
        {
            return new Guidance();
        }

        /// <summary>
        /// Keeps the list of libraries defined in this guidance explorer.
        /// </summary>
        private LibraryCollection _libraries = LibraryCollection.New();

        /// <summary>
        /// The list of libraries that has been deleted from the UI.
        /// </summary>
        private LibraryCollection _deletedLibraries = LibraryCollection.New();

        /// <summary>
        /// The list of guidance items that has been deleted from the UI.
        /// </summary>
        private GuidanceItemCollection _deletedGuidanceItems = GuidanceItemCollection.New();

        /// <summary>
        /// The list of root folders and views created by the user.
        /// </summary>
        private UserViews _userViews = UserViews.New();

		private GlobalViews _globalViews = GlobalViews.New();

        /// <summary>
        /// The list of projects guidance
        /// </summary>
        //private FolderCollection _projectFolders = FolderCollection.New();

        /// <summary>
        /// The kind of client that is being used.
        /// </summary>
        private ClientFlavour _clientFlavour;

        /// <summary>
        /// The columns for this collection.
        /// </summary>
        private ColumnCollection _columns;

        /// <summary>
        /// The columns for LibrariesNode.
        /// </summary>
        private ColumnCollection _librariesNodeColumns;


        /// <summary>
        /// Default private constructor.
        /// </summary>
        protected Guidance() { }

        /// <summary>
        /// The list of libraries.
        /// </summary>
        public LibraryCollection Libraries
        {
            get { return _libraries; }
        }

        /// <summary>
        /// The list of root folders, views and checklist associated to a solution
        /// </summary>
        public SolutionViews SolutionViews { get; set; }

        /// <summary>
        /// The list of root folders and views created by the user.
        /// </summary>
        public UserViews UserViews
        {
            get { return _userViews; }
            set { _userViews = value; }
        }

		public GlobalViews GlobalViews
		{
			get { return _globalViews; }
			set { _globalViews = value; }
		}

        ///// <summary>
        ///// The list of root projects guidances
        ///// </summary>
        //public FolderCollection ProjectFolders
        //{
        //    get { return _projectFolders; }
        //    set { _projectFolders = value; }
        //}


        /// <summary>
        /// The list of libraries that has been deleted from the UI.
        /// </summary>
        public LibraryCollection DeletedLibraries
        {
            get { return _deletedLibraries; }
        }

        /// <summary>
        /// The list of guidance items that has been deleted from the UI.
        /// </summary>
        public GuidanceItemCollection DeletedGuidanceItems
        {
            get { return _deletedGuidanceItems; }
        }

        /// <summary>
        /// The kind of client that is being used.
        /// </summary>
        public ClientFlavour ClientFlavour
        {
            get { return _clientFlavour; }
            set { _clientFlavour = value; }
        }

        #region IGuidanceItemContainer Members

        /// <summary>
        /// Return the columns for the guidance view.
        /// </summary>
        public ColumnCollection DefaultColumns
        {
            get
            {
                if (_columns == null)
                {
                    _columns = ColumnCollection.DefaultColumns(GuidanceType.New(GuidanceType.DefaultTypeName));
                }
                return _columns;
            }
            set
            {
                _columns = value;
            }
        }

        /// <summary>
        /// Return the columns for the LibrariesNode
        /// </summary>
        public ColumnCollection Columns
        {
            get
            {
                if (_librariesNodeColumns == null)
                {
                    _librariesNodeColumns = ColumnCollection.DefaultColumns(GuidanceType.New(GuidanceType.DefaultTypeName));
                }
                return _librariesNodeColumns;
            }
            set
            {
                _librariesNodeColumns = value;
            }
        }

        /// <summary>
        /// Guidance has its own items, which is the union of the items for the contained libraries.
        /// </summary>
        public bool HasItems
        {
            get { return true; }
        }

        /// <summary>
        /// The items collection can't be set.
        /// </summary>
        public bool CanSetItems
        {
            get { return false; }
        }

        /// <summary>
        /// The items on this guidance.
        /// </summary>
        public GuidanceItemCollection Items
        {
            get
            {
                GuidanceItemCollection items = GuidanceItemCollection.New();
                foreach (Library library in _libraries.Values)
                {
                    foreach (GuidanceItem item in library.Items.Values)
                    {
                        if (!items.ContainsKey(item.Id))
                        {
                            items.Add(item.Id, item);
                        }
                    }
                }
                return items;
            }
            set { throw new Exception("Guidance does not have Items."); }
        }

        #endregion

        #region IEnumerable<GuidanceItem> Members

        public IEnumerator<GuidanceItem> GetEnumerator()
        {
            foreach (Library library in _libraries.Values)
            {
                foreach (GuidanceItem item in library.Items.Values)
                {
                    yield return item;
                }
            }
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        /// <summary>
        /// Searches the entire library and resolve the reference to the GuidanceItemFileReference.
        /// </summary>
        /// <param name="guidanceItem">The guidance item to resolve.</param>
        /// <returns></returns>
        public GuidanceItemFileReference GetGuidanceItemFileReference(GuidanceItem guidanceItem)
        {
            if (guidanceItem.ReferencedItem == null)
            {
                //Iterate through all the items of all the libraries.
                foreach (GuidanceItemFileReference item in this)
                {
                    if (item.Id == guidanceItem.Id)
                    {
                        guidanceItem.ReferencedItem = item;
                        break;
                    }
                    else
                    {
                        //Not this item, keep looking.
                    }
                }
            }
            return guidanceItem.ReferencedItem;
        }

        public GuidanceItemFileReference[] GetGuidanceItemFileReference(GuidanceItem[] guidanceItem)
        {
            int count = guidanceItem.Length;
            GuidanceItemFileReference[] items = new GuidanceItemFileReference[count];
            for (int i = 0; i < count; i++)
            {
                items[i] = GetGuidanceItemFileReference(guidanceItem[i]);
            }

            return items;
        }


    }
}

